/*
 * Copyright (c) 2011 Auzingers
 * Created by Oui-IT
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package com.auzingers.docsorganizer.googleapi;

import com.auzingers.docsorganizer.DocsOrganizerApplication;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.InputStreamContent;
import com.google.api.client.xml.XmlNamespaceDictionary;
import com.google.api.services.samples.shared.gdata.xml.GDataXmlClient;

import android.util.Log;

import java.io.ByteArrayInputStream;
import java.io.IOException;

/** Client api for accessing Google documents. */
public class DocsClient extends GDataXmlClient {

    private static final String TAG = DocsOrganizerApplication.APP_TAG + ".DocsClient";

    static final XmlNamespaceDictionary DICTIONARY = new XmlNamespaceDictionary()
            .set("", "http://www.w3.org/2005/Atom").set("app", "http://www.w3.org/2007/app")
            .set("batch", "http://schemas.google.com/gdata/batch").set("docs", "http://schemas.google.com/docs/2007")
            .set("gAcl", "http://schemas.google.com/acl/2007").set("gd", "http://schemas.google.com/g/2005")
            .set("openSearch", "http://a9.com/-/spec/opensearch/1.1/")
            .set("xml", "http://www.w3.org/XML/1998/namespace");

    /**
     * Creates a new google docs client with the given request factory.
     * @param requestFactory request factory to use
     */
    public DocsClient(HttpRequestFactory requestFactory) {
        super("3", requestFactory, DICTIONARY);
        setPartialResponse(false);
    }

    /**
     * Returns the string that is the result of calling the given url.
     * @param url url to call
     * @return result of the request
     * @throws IOException if an io error occured
     */
    public String getString(GenericUrl url) throws IOException {
        final HttpRequest request = getRequestFactory().buildGetRequest(url);
        final HttpResponse response = execute(request);
        return response.parseAsString();
    }

    /**
     * Test method to remove a document from a collection.
     * @param documentId id of the document to remove, i.e.
     *   0Anca1VegIvJhdDNfVjZWV08yNVhiQTlpVFVDYTRqS1E
     * @param collectionId id of the collection to remove the document from, i.e.
     *   folder%3A0B3ca1VegIvJhYzljYTA0YTMtNmRjZC00OWMxLWFiM2UtYmYxN2MzMTRlMzA3
     * @throws IOException if an io error occured
     */
    public void removeDocumentFromCollection(String documentId, String collectionId) throws IOException {
        final GenericUrl url = new GenericUrl("https://docs.google.com/feeds/default/private/full/" + collectionId
                + "/contents/" + documentId);
        final HttpRequest request = getRequestFactory().buildDeleteRequest(url);
        request.getHeaders().put("If-Match", "*");
        final HttpResponse response = execute(request);
        System.out.println(response.parseAsString());
    }

    /**
     * Removes the given document or collection.
     * @param resourceId id of the resource to remove
     * @throws IOException if an io error occured
     */
    public void deleteEntry(String resourceId) throws IOException {
        final GenericUrl url = new GenericUrl("https://docs.google.com/feeds/default/private/full/" + resourceId);
        final HttpRequest request = getRequestFactory().buildDeleteRequest(url);
        request.getHeaders().put("If-Match", "*");
        final HttpResponse response = execute(request);
        System.out.println(response.parseAsString());

    }

    /**
     * Copies a document and creates a new document in the root collection.
     * @param documentId of the document to copy
     * @param newName new name of the copy
     * @return documentId of the newly created document
     * @throws IOException if an io error occured
     */
    public String copyDocument(String documentId, String newName) throws IOException {
        //send request
        final GenericUrl url = new GenericUrl("https://docs.google.com/feeds/default/private/full");
        final String xml = "<?xml version='1.0' encoding='UTF-8'?>" + "<entry xmlns=\"http://www.w3.org/2005/Atom\">"
                + "<id>https://docs.google.com/feeds/default/private/full/document%3A" + documentId + "</id> "
                + "<title>" + newName + "</title> " + "</entry>";
        final HttpResponse response = sendPostRequest(url, xml);
        //get document if from response
        final Object location = response.getHeaders().get("Location");
        if (location instanceof String) {
            final String strLocation = (String) location;
            final String sep = "%3A";
            final int idx = strLocation.indexOf(sep);
            if (idx > 0) {
                final String id = strLocation.substring(idx + sep.length());
                return id;
            }
        }
        Log.w(TAG, "Didn't manage to extract id of copied document");
        return null;
    }

    /**
     * Adds a document to a collection.
     * @param documentId id of the document to add
     * @param collectionId id of the collection
     * @throws IOException if an io error occured
     */
    public void addDocumentToCollection(String documentId, String collectionId) throws IOException {
        final GenericUrl url = new GenericUrl("https://docs.google.com/feeds/default/private/full/folder%3A"
                + collectionId + "/contents");
        final String xml = "<?xml version='1.0' encoding='UTF-8'?>" + "<entry xmlns=\"http://www.w3.org/2005/Atom\">"
                + "<id>https://docs.google.com/feeds/default/private/full/document:" + documentId + "</id>"
                + "</entry>";
        sendPostRequest(url, xml);
    }

    /**
     * Helper method for sending post requests to Google.
     * @param url target url
     * @param content content to send
     * @return HttpResponse of request
     * @throws IOException if an io error occured
     */
    private HttpResponse sendPostRequest(GenericUrl url, String content) throws IOException {
        final InputStreamContent isContent = new InputStreamContent("text/plain", new ByteArrayInputStream(
                content.getBytes("UTF-8")));
        final HttpRequest request = getRequestFactory().buildPostRequest(url, isContent);
        request.getHeaders().put("Content-Type", "application/atom+xml");
        request.getHeaders().put("GData-Version", "3.0");
        return execute(request);
    }
}